﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Web;

using System.IO;
using System.Data;
using BioStarCSharp;
using System.Runtime.InteropServices;
using System.Net;
using System.Text;

namespace LEEAAttendanceControl.Web.Services
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class AttendanceService
    {
        AttendanceDBEntities context = new AttendanceDBEntities();
        private byte[] m_TemplateData = null;
        public const int MAX_DEVICE = 128;
        public const int TEMPLATE_SIZE = 384;


        [OperationContract]
        public List<Device> GetDevices()
        {
            int m_Handle = -1;
            int m_NumOfDevice = 0;
            uint[] m_DeviceID;
            int[] m_DeviceType;
            uint[] m_DeviceAddr;

            m_DeviceID = new uint[MAX_DEVICE];
            m_DeviceType = new int[MAX_DEVICE];
            m_DeviceAddr = new uint[MAX_DEVICE];
            int result = BSSDK.BS_InitSDK();
            if (result == BSSDK.BS_SUCCESS)
            {
                result = BSSDK.BS_OpenInternalUDP(ref m_Handle);
                if (result == BSSDK.BS_SUCCESS)
                {
                    try
                    {
                        result = BSSDK.BS_SearchDeviceInLAN(m_Handle, ref m_NumOfDevice, m_DeviceID, m_DeviceType, m_DeviceAddr);
                        if (result == BSSDK.BS_SUCCESS)
                        {
                            List<Device> lstOfDevices = new List<Device>();
                            for (int i = 0; i < m_DeviceID.Length; i++)
                            {
                                if (m_DeviceID[i] != 0)
                                {
                                    Device d = new Device() { DeviceId = m_DeviceID[i].ToString(), Addr = m_DeviceAddr[i], Type = m_DeviceType[i], Handle = m_Handle };
                                    lstOfDevices.Add(d);
                                }
                            }
                            return lstOfDevices;

                        }
                    }
                    catch
                    {
                    }
                }
            }
            return null;
        }
        BSSDK.BSIPConfig m_ConfigBST;

        [OperationContract]
        public FingerInfo GetFingersInfo(FingerInfo fingerinfo)
        {
            int handle = 0;
            try
            {
                int configSize = 0;
                Location location = (from l in context.Locations
                                     where l.LocationId == fingerinfo.LocationId
                                     select l).FirstOrDefault();
                if (location == null) return null;

                List<Device> lstOfDevices = GetDevices();
                Device dev = (from d in lstOfDevices
                              where d.DeviceId == location.DeviceId
                              select d).FirstOrDefault();

                if (dev == null) return null;

                IntPtr config = Marshal.AllocHGlobal(Marshal.SizeOf(m_ConfigBST));
                int result = BSSDK.BS_ReadConfigUDP(dev.Handle, dev.Addr, uint.Parse(location.DeviceId), BSSDK.BS_CONFIG_TCPIP, ref configSize, config);
                if (result != BSSDK.BS_SUCCESS)
                {
                    Marshal.FreeHGlobal(config);
                    throw new Exception();
                }
                m_ConfigBST = (BSSDK.BSIPConfig)Marshal.PtrToStructure(config, typeof(BSSDK.BSIPConfig));
                Marshal.FreeHGlobal(config);
                uint port = 0;
                if (m_ConfigBST.useServer)
                {
                    port = m_ConfigBST.serverPort;
                }
                else
                {
                    port = m_ConfigBST.port;
                }
                IPAddress addr = new IPAddress(dev.Addr);
                result = BSSDK.BS_OpenSocket(addr.ToString(), (int)port, ref handle);
                if (result == BSSDK.BS_SUCCESS)
                {
                    byte[] templateData = new byte[TEMPLATE_SIZE];
                    //Finger 1
                    result = BSSDK.BS_ScanTemplate(handle, templateData);
                    if (result != BSSDK.BS_SUCCESS)
                    {
                        throw new Exception();
                    }
                    m_TemplateData = new byte[TEMPLATE_SIZE * 2 * 2];
                    Buffer.BlockCopy(templateData, 0, m_TemplateData, 0, TEMPLATE_SIZE);
                    result = BSSDK.BS_ScanTemplate(handle, templateData);
                    if (result != BSSDK.BS_SUCCESS)
                    {
                        throw new Exception();
                    }
                    Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE, TEMPLATE_SIZE);
                    for (int i = 0; i < TEMPLATE_SIZE * 2; i++)
                    {
                        fingerinfo.FingerChecksum1 += m_TemplateData[i];
                    }
                    //Finger 2
                    result = BSSDK.BS_ScanTemplate(handle, templateData);
                    if (result != BSSDK.BS_SUCCESS)
                    {
                        throw new Exception();
                    }
                    Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE * 2, TEMPLATE_SIZE);
                    result = BSSDK.BS_ScanTemplate(handle, templateData);
                    if (result != BSSDK.BS_SUCCESS)
                    {
                        throw new Exception();
                    }
                    Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE * 3, TEMPLATE_SIZE);
                    for (int i = 0; i < TEMPLATE_SIZE * 2; i++)
                    {
                        fingerinfo.FingerChecksum2 += m_TemplateData[TEMPLATE_SIZE * 2 + i];
                    }
                    fingerinfo.FingerTemplate = m_TemplateData;
                    fingerinfo.Handle = handle;
                    AddEmployeeToDevice(fingerinfo);
                    return fingerinfo;//new FingerInfo() { FingerTemplate = m_TemplateData, FingerChecksum1 = fingerChecksum1, FingerChecksum2 = fingerChecksum2,Handle=handle};
                }
                return null;
            }
            finally
            {
                BSSDK.BS_CloseSocket(handle);
            }
        }

        [OperationContract]
        public void AddEmployeeToDevice(FingerInfo fingerinfo)
        {
            BSSDK.BSUserHdrEx userHdr = new BSSDK.BSUserHdrEx();
            userHdr.checksum = new ushort[5];
            byte[] nameArray = new byte[33];
            int j = 0;
            foreach (char c in fingerinfo.Name.ToCharArray())
            {
                nameArray[j] = (byte)c;
                j++;
            }
            userHdr.name = nameArray;
            userHdr.department = new byte[33];
            userHdr.password = new byte[17];
            userHdr.authLimitCount = 0;
            userHdr.timedAntiPassback = 0;
            userHdr.disabled = 0;
            userHdr.numOfFinger = 2;
            userHdr.checksum[0] = (ushort)fingerinfo.FingerChecksum1;
            userHdr.checksum[1] = (ushort)fingerinfo.FingerChecksum2;
            userHdr.ID = fingerinfo.Id;
            userHdr.adminLevel = (ushort)((fingerinfo.UserLevel == 1) ? BSSDK.BS_USER_ADMIN : BSSDK.BS_USER_NORMAL);
            userHdr.securityLevel = (ushort)(fingerinfo.SecurityLevel + BSSDK.BS_USER_SECURITY_DEFAULT);
            userHdr.bypassCard = (byte)fingerinfo.CardType;
            userHdr.startDateTime = (uint)((DateTime.Now.AddYears(-5).Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
            userHdr.expireDateTime = (uint)((DateTime.Now.AddYears(30).Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
            userHdr.duressMask = 0;
            userHdr.duressMask |= 0x01;
            userHdr.authMode = (ushort)(fingerinfo.AuthMode + BSSDK.BS_AUTH_FINGER_ONLY - 1);
            try
            {
                //user card id
                userHdr.cardID = UInt32.Parse("", System.Globalization.NumberStyles.HexNumber);
            }
            catch (Exception)
            {
                userHdr.cardID = 0;
            }
            try
            {
                //cardCustomID.Text = "";
                userHdr.customID = (byte)Int32.Parse("");
            }
            catch (Exception)
            {
                userHdr.customID = 0;
            }
            userHdr.version = BSSDK.BE_CARD_VERSION_1;
            try
            {
                //accessGroup.Text
                userHdr.accessGroupMask = UInt32.Parse("", System.Globalization.NumberStyles.HexNumber);
            }
            catch (Exception)
            {
                userHdr.accessGroupMask = 0xffffffff;
            }
            IntPtr userInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BSSDK.BSUserHdrEx)));
            Marshal.StructureToPtr(userHdr, userInfo, true);
            int result = BSSDK.BS_EnrollUserEx(fingerinfo.Handle, userInfo, fingerinfo.FingerTemplate);
            Marshal.FreeHGlobal(userInfo);
            if (result != BSSDK.BS_SUCCESS)
            {
                return;
            }
        }

        [OperationContract]
        public List<LogRecord> ReadLog(int locationId)
        {
            int m_NumOfLog = 0;
            int handle = 0;
            int configSize = 0;
            List<LogRecord> lstOfRecords = new List<LogRecord>();
            try
            {
                Location location = (from l in context.Locations
                                     where l.LocationId == locationId
                                     select l).FirstOrDefault();

                if (location == null) return null;

                List<Device> lstOfDevices = GetDevices();
                Device dev = (from d in lstOfDevices
                              where d.DeviceId == location.DeviceId
                              select d).FirstOrDefault();

                if (dev == null) return null;

                IntPtr config = Marshal.AllocHGlobal(Marshal.SizeOf(m_ConfigBST));
                int result = BSSDK.BS_ReadConfigUDP(dev.Handle, dev.Addr, uint.Parse(location.DeviceId), BSSDK.BS_CONFIG_TCPIP, ref configSize, config);
                if (result != BSSDK.BS_SUCCESS)
                {
                    Marshal.FreeHGlobal(config);
                    throw new Exception();
                }
                m_ConfigBST = (BSSDK.BSIPConfig)Marshal.PtrToStructure(config, typeof(BSSDK.BSIPConfig));
                Marshal.FreeHGlobal(config);
                uint port = 0;
                if (m_ConfigBST.useServer)
                {
                    port = m_ConfigBST.serverPort;
                }
                else
                {
                    port = m_ConfigBST.port;
                }
                IPAddress addr = new IPAddress(dev.Addr);
                result = BSSDK.BS_OpenSocket(addr.ToString(), (int)port, ref handle);
                BSSDK.BS_SetDeviceID(handle, uint.Parse(dev.DeviceId), dev.Type);

                ///////////////
                BSSDK.BS_GetLogCount(handle, ref m_NumOfLog);

                IntPtr lRecord = Marshal.AllocHGlobal(m_NumOfLog * Marshal.SizeOf(typeof(BSSDK.BSLogRecord)));
                int logTotalCount = 0;
                int logCount = 0;
                do
                {
                    IntPtr buf = new IntPtr(lRecord.ToInt32() + logTotalCount * Marshal.SizeOf(typeof(BSSDK.BSLogRecord)));
                    if (logTotalCount == 0)
                    {
                        result = BSSDK.BS_ReadLog(handle, 0, 0, ref logCount, buf);
                    }
                    else
                    {
                        result = BSSDK.BS_ReadNextLog(handle, 0, 0, ref logCount, buf);
                    }

                    if (result != BSSDK.BS_SUCCESS)
                    {
                        Marshal.FreeHGlobal(lRecord);
                        return null;
                    }

                    logTotalCount += logCount;

                } while (logCount == 8192);
                for (int i = 0; i < logTotalCount; i++)
                {
                    BSSDK.BSLogRecord record = (BSSDK.BSLogRecord)Marshal.PtrToStructure(new IntPtr(lRecord.ToInt32() + i * Marshal.SizeOf(typeof(BSSDK.BSLogRecord))), typeof(BSSDK.BSLogRecord));
                    if (record.eventType == 55 || record.eventType == 56)
                    {
                        LogRecord logrecord = new LogRecord();
                        logrecord.UserId = record.userID;
                        logrecord.EventTime = new DateTime(1970, 1, 1).AddSeconds(record.eventTime);
                        logrecord.EventType = record.eventType;
                        lstOfRecords.Add(logrecord);
                    }
                }
                Marshal.FreeHGlobal(lRecord);
                return lstOfRecords;
            }
            finally
            {
                BSSDK.BS_CloseSocket(handle);
            }
        }

        [OperationContract]
        public void SaveLog(int locationid)
        {
            List<LogRecord> lstOfLogRecords = ReadLog(locationid);
            foreach (LogRecord lr in lstOfLogRecords)
            {
                Attendance attend = new Attendance();
                attend.EmployeeID = (from e in context.Employees
                                     where e.EmployeeCode == lr.UserId
                                     select e.EmployeeID).FirstOrDefault();
                attend.DataTime = lr.EventTime;
                attend.ShiftID = (from s in context.ShiftAssignments
                                  where s.EmployeeID == attend.EmployeeID && s.AssignmentFrom <= attend.DataTime && s.AssignmentTo >= attend.DataTime
                                  select s.ShiftID).FirstOrDefault();
                attend.Status = lr.EventType == 55 ? 1 : 0;
                context.Attendances.AddObject(attend);
            }
            context.SaveChanges();
        }

        [OperationContract]
        public void Connect(uint id, string name, string m_DeviceID, int userLevel, int securityLevel, int cardType, int authMode)
        {
            userLevel = 0;
            securityLevel = 0;
            cardType = 0;
            authMode = 0;
            m_DeviceID = "23475";
            id = 12;
            name = "ahmedoss";
            int configSize = 0;
            List<Device> lstOfDevices = GetDevices();
            Device dev = (from d in lstOfDevices
                          where d.DeviceId == m_DeviceID.ToString()
                          select d).FirstOrDefault();

            if (dev != null)
            {
                IntPtr config = Marshal.AllocHGlobal(Marshal.SizeOf(m_ConfigBST));

                int result = BSSDK.BS_ReadConfigUDP(dev.Handle, dev.Addr, uint.Parse(m_DeviceID), BSSDK.BS_CONFIG_TCPIP, ref configSize, config);


                if (result != BSSDK.BS_SUCCESS)
                {
                    Marshal.FreeHGlobal(config);
                    throw new Exception();
                }

                m_ConfigBST = (BSSDK.BSIPConfig)Marshal.PtrToStructure(config, typeof(BSSDK.BSIPConfig));

                Marshal.FreeHGlobal(config);

                uint port = 0;
                if (m_ConfigBST.useServer)
                {
                    port = m_ConfigBST.serverPort;
                }
                else
                {
                    port = m_ConfigBST.port;
                }
                IPAddress addr = new IPAddress(dev.Addr);
                int handle = 0;
                result = BSSDK.BS_OpenSocket(addr.ToString(), (int)port, ref handle);
                if (result == BSSDK.BS_SUCCESS)
                {

                    int fingerChecksum1 = 0;
                    int fingerChecksum2 = 0;

                    byte[] templateData = new byte[TEMPLATE_SIZE];

                    int numOfFinger = 0;

                    if (true)
                    {
                        numOfFinger++;

                        result = BSSDK.BS_ScanTemplate(handle, templateData);

                        if (result != BSSDK.BS_SUCCESS)
                        {
                            throw new Exception();
                        }
                        m_TemplateData = new byte[TEMPLATE_SIZE * 2 * 2];

                        Buffer.BlockCopy(templateData, 0, m_TemplateData, 0, TEMPLATE_SIZE);

                        result = BSSDK.BS_ScanTemplate(handle, templateData);

                        if (result != BSSDK.BS_SUCCESS)
                        {
                            throw new Exception();
                        }

                        Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE, TEMPLATE_SIZE);

                        for (int i = 0; i < TEMPLATE_SIZE * 2; i++)
                        {
                            fingerChecksum1 += m_TemplateData[i];
                        }
                        if (true)
                        {
                            numOfFinger++;

                            result = BSSDK.BS_ScanTemplate(handle, templateData);

                            if (result != BSSDK.BS_SUCCESS)
                            {
                                throw new Exception();
                            }

                            Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE * 2, TEMPLATE_SIZE);

                            result = BSSDK.BS_ScanTemplate(handle, templateData);

                            if (result != BSSDK.BS_SUCCESS)
                            {
                                throw new Exception();
                            }

                            Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE * 3, TEMPLATE_SIZE);

                            for (int i = 0; i < TEMPLATE_SIZE * 2; i++)
                            {
                                fingerChecksum2 += m_TemplateData[TEMPLATE_SIZE * 2 + i];
                            }
                        }

                        ///Add User To Device
                        BSSDK.BSUserHdrEx userHdr = new BSSDK.BSUserHdrEx();
                        userHdr.checksum = new ushort[5];
                        byte[] nameArray = new byte[33];
                        int j = 0;
                        foreach (char c in name.ToCharArray())
                        {
                            nameArray[j] = (byte)c;
                            j++;
                        }
                        userHdr.name = nameArray;//new byte[33]; //Encoding.ASCII.GetBytes("ahmedos");
                        userHdr.department = new byte[33];
                        userHdr.password = new byte[17];
                        userHdr.authLimitCount = 0;
                        userHdr.timedAntiPassback = 0;
                        userHdr.disabled = 0;
                        userHdr.numOfFinger = 2;
                        userHdr.checksum[0] = (ushort)fingerChecksum1;
                        userHdr.checksum[1] = (ushort)fingerChecksum2;
                        userHdr.ID = id;
                        userHdr.adminLevel = (ushort)((userLevel == 1) ? BSSDK.BS_USER_ADMIN : BSSDK.BS_USER_NORMAL);
                        userHdr.securityLevel = (ushort)(securityLevel + BSSDK.BS_USER_SECURITY_DEFAULT);
                        userHdr.bypassCard = (byte)cardType;
                        userHdr.startDateTime = (uint)((DateTime.Now.AddYears(-5).Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                        userHdr.expireDateTime = (uint)((DateTime.Now.AddYears(30).Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                        userHdr.duressMask = 0;
                        userHdr.duressMask |= 0x01;
                        userHdr.authMode = (ushort)(authMode + BSSDK.BS_AUTH_FINGER_ONLY - 1);
                        try
                        {
                            //user card id
                            userHdr.cardID = UInt32.Parse("", System.Globalization.NumberStyles.HexNumber);
                        }
                        catch (Exception)
                        {
                            userHdr.cardID = 0;
                        }
                        try
                        {
                            //cardCustomID.Text = "";
                            userHdr.customID = (byte)Int32.Parse("");
                        }
                        catch (Exception)
                        {
                            userHdr.customID = 0;
                        }
                        userHdr.version = BSSDK.BE_CARD_VERSION_1;
                        try
                        {
                            //accessGroup.Text
                            userHdr.accessGroupMask = UInt32.Parse("", System.Globalization.NumberStyles.HexNumber);
                        }
                        catch (Exception)
                        {
                            userHdr.accessGroupMask = 0xffffffff;
                        }
                        IntPtr userInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BSSDK.BSUserHdrEx)));
                        Marshal.StructureToPtr(userHdr, userInfo, true);
                        result = BSSDK.BS_EnrollUserEx(handle, userInfo, m_TemplateData);
                        Marshal.FreeHGlobal(userInfo);
                        if (result != BSSDK.BS_SUCCESS)
                        {
                            return;
                        }
                    }
                }
            }
        }

        [OperationContract]
        public List<TreeNode> BuildStructure(string role, DateTime day)
        {
            AttendanceDBEntities context = new AttendanceDBEntities();

            List<TreeNode> structure = new List<TreeNode>();

            if (role == "Administrator")
            {
                foreach (Company company in context.Companies)
                {
                    List<TreeNode> depNodes = new List<TreeNode>();

                    foreach (Department dep in context.Departments.Where(depa => depa.CompanyID == company.ID))
                    {
                        depNodes.Add(new TreeNode(1, dep.DepartmentName, company.ID, dep.DepartmentID, 0
                            , "White", BuildDepStructure(dep.CompanyID.Value, dep.DepartmentID, day).ToArray()));
                    }

                    Department firstDep = context.Departments.Where(de => de.CompanyID == company.ID).FirstOrDefault();

                    structure.Add(new TreeNode(0, company.CompanyName, company.ID
                        , 0, 0, "White", depNodes.ToArray()));
                }
            }

            if (role == "Company Manager")
            {
                int comID = (int)context.Users.Where(user =>
                    user.Login == HttpContext.Current.User.Identity.Name).FirstOrDefault().CompanyID;

                List<TreeNode> depNodes = new List<TreeNode>();

                foreach (Department dep in context.Departments.Where(depa => depa.CompanyID == comID))
                {
                    depNodes.Add(new TreeNode(1, dep.DepartmentName, comID, dep.DepartmentID, 0
                        , "White", BuildDepStructure(comID, dep.DepartmentID, day).ToArray()));
                }

                Department firstDep = context.Departments.Where(de => de.CompanyID == comID).FirstOrDefault();

                structure.Add(new TreeNode(0, context.Companies.Where(com => com.ID == comID).FirstOrDefault().CompanyName
                    , comID, 0, 0, "White", depNodes.ToArray()));
            }

            if (role == "Department Manager")
            {
                int comID = (int)context.Users.Where(user =>
                    user.Login == HttpContext.Current.User.Identity.Name).FirstOrDefault().CompanyID;

                int depID = (int)context.Users.Where(user =>
                    user.Login == HttpContext.Current.User.Identity.Name).FirstOrDefault().DepartmentID;

                List<TreeNode> depNodes = new List<TreeNode>();

                depNodes.Add(new TreeNode(1, context.Departments.Where(dep => dep.DepartmentID == depID).FirstOrDefault().DepartmentName
                    , comID, depID, 0, "White", BuildDepStructure(comID, depID, day).ToArray()));

                structure.Add(new TreeNode(0, context.Companies.Where(com => com.ID == comID).FirstOrDefault().CompanyName
                    , comID, depID, 0, "White", depNodes.ToArray()));
            }

            return structure;
        }

        public List<TreeNode> BuildDepStructure(int comID, int depID, DateTime day)
        {
            AttendanceDBEntities context = new AttendanceDBEntities();

            IEnumerable<Punch> punches = context.Punches.Where(p => p.PunchType == "IN"
                && context.Employees.Where(emp => emp.CompanyID == comID && emp.DepartmentID == depID)
                    .Contains(context.Employees.Where(e => e.EmployeeID == p.EmployeeID).FirstOrDefault())
                && p.DataTime.Value.Day == day.Day && p.DataTime.Value.Month == day.Month
                && p.DataTime.Value.Year == day.Year).OrderBy(e=>e.Employee.FirstName).AsEnumerable<Punch>();

            List<TreeNode> empNodes = new List<TreeNode>();

            foreach (Employee emp in context.Employees.Where(em => em.CompanyID == comID && em.DepartmentID == depID).OrderBy(e=>e.FirstName))
            {
                string color = string.Empty;

                if (punches.Where(p => p.EmployeeID == emp.EmployeeID).Count() > 0)
                {
                    color = "Orange";
                }
                else
                {
                    color = "Gray";
                }

                empNodes.Add(new TreeNode(2, emp.FirstName + " " + emp.LastName, comID, depID, emp.EmployeeID, color));
            }

            return empNodes;
        }

        [OperationContract]
        public TreeNode BuildEmployeeStructure(DateTime day, string userName)
        {
            AttendanceDBEntities context = new AttendanceDBEntities();

            Employee employee = context.Employees.Where(emp => emp.Login == userName).FirstOrDefault();

            int companyID = employee.CompanyID.Value;
            int departmentID = employee.DepartmentID.Value;
            int employeeID = employee.EmployeeID;

            IEnumerable<Punch> punches = context.Punches.Where(p => p.PunchType == "IN"
                && context.Employees.Where(emp => emp.CompanyID == companyID && emp.DepartmentID == departmentID
                    && emp.EmployeeID == employeeID)
                        .Contains(context.Employees.Where(e => e.EmployeeID == p.EmployeeID).FirstOrDefault())
                && p.DataTime.Value.Day == day.Day && p.DataTime.Value.Month == day.Month
                && p.DataTime.Value.Year == day.Year).AsEnumerable<Punch>();

            string color = string.Empty;

            if (punches.Count() > 0)
            {
                color = "Orange";
            }
            else
            {
                color = "Gray";
            }

            TreeNode employeeNode = new TreeNode(2, employee.FirstName + " " + employee.LastName, companyID, departmentID
                , employeeID, color);

            TreeNode departmentNode = new TreeNode(1, employee.Department.DepartmentName, companyID, departmentID
                , employeeID, "White", employeeNode);

            TreeNode companyNode = new TreeNode(0, employee.Company.CompanyName, companyID, departmentID, employeeID
                , "White", departmentNode);

            return companyNode;
        }

        [OperationContract]
        public void WriteUserSelection(List<int> employees, Dictionary<int, List<int>> days, DateTime from, DateTime to
            , string type)
        {
            AttendanceDBEntities context = new AttendanceDBEntities();

            if (type == "New")
            {
                foreach (ShiftAssignment assignment in context.ShiftAssignments.Where(sa
                => employees.Contains(sa.EmployeeID.Value)))
                {
                    if (from.Date >= assignment.AssignmentFrom.Value.Date
                        && from.Date <= assignment.AssignmentTo.Value.Date)
                    {
                        if (from.Date > assignment.AssignmentFrom.Value.Date
                                && from.Date < assignment.AssignmentTo.Value.Date)
                        {
                            assignment.AssignmentTo = from.Date.AddDays(-1);
                        }
                    }
                }
            }

            context.SaveChanges();

            foreach (int emp in employees)
            {
                foreach (int shift in days.Keys)
                {
                    ShiftAssignment newAssign = new ShiftAssignment()
                        {
                            EmployeeID = emp,
                            ShiftID = shift,
                            AssignmentFrom = from,
                            AssignmentTo = to
                        };

                    context.ShiftAssignments.AddObject(newAssign);

                    context.SaveChanges();

                    foreach (int day in days[shift])
                    {
                        context.ShiftAssignmentDays.AddObject(new ShiftAssignmentDay()
                        {
                            ShiftAssignmentID = newAssign.ID,
                            DayID = day
                        });
                    }

                    context.SaveChanges();
                }
            }
        }

        [OperationContract]
        public void SetReportData(List<int> employees, DateTime from, DateTime to)
        {
            HttpContext.Current.Session["Employees"] = employees;
            HttpContext.Current.Session["From"] = from;
            HttpContext.Current.Session["To"] = to;
        }
    }
}
